package cn.wolfcode.web.controller;

import cn.wolfcode.common.domain.UserInfo;
import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.common.web.anno.RequireLogin;
import cn.wolfcode.domain.OrderInfo;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.mq.MQConstant;
import cn.wolfcode.mq.OrderMessage;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.IOrderInfoService;
import cn.wolfcode.service.ISeckillProductService;
import cn.wolfcode.util.DateUtil;
import cn.wolfcode.util.UserUtil;
import cn.wolfcode.web.msg.SeckillCodeMsg;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bouncycastle.jcajce.provider.digest.Skein;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.nio.channels.SelectionKey;
import java.util.concurrent.ConcurrentHashMap;


@RestController
@RequestMapping("/order")
@Slf4j
public class OrderInfoController {
    @Autowired
    private ISeckillProductService seckillProductService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private IOrderInfoService orderInfoService;

    public static ConcurrentHashMap<Long,Boolean> local_flag = new ConcurrentHashMap<>();

    @RequestMapping("/find")
    public Result<OrderInfo> find(String orderNo,HttpServletRequest request){
        //如果传递进来的订单号为null，抛出异常
        if(StringUtils.isEmpty(orderNo)){
            throw new BusinessException(SeckillCodeMsg.OPT_SECKILL_ERROR);
        }
        //根据订单号查询对象的用户对象
        OrderInfo orderInfo = orderInfoService.find(orderNo);
        if(orderInfo == null){
            throw new BusinessException(SeckillCodeMsg.OPT_SECKILL_ERROR);
        }
        //获取请求头token,为了获取userInfo对象
        String token = request.getHeader("token");
        UserInfo userInfo = UserUtil.getUser(redisTemplate, token);
        //如果用户的手机号和订单的手机号不一致，抛出异常
        if(!userInfo.getPhone().equals(orderInfo.getUserId())){
            throw new BusinessException(SeckillCodeMsg.OPT_SECKILL_ERROR);
        }
        return Result.success(orderInfo);
    }

    @RequestMapping("/doSeckill")
    //需要先登录才能进行抢购
    @RequireLogin
    public Result<String> doSeckill(int time, Long seckillId, HttpServletRequest request){
        //合法性效验
        if(StringUtils.isEmpty(time + "") || StringUtils.isEmpty(seckillId + "")){
            throw new BusinessException(SeckillCodeMsg.OPT_SECKILL_ERROR);
        }

        //判断本地标识，如果本地标识为true，标识redis中的库存数量已经减少到了负数，就直接抛出异常
        Boolean isFlag = local_flag.get(seckillId);
        if(isFlag != null && isFlag){
            throw new BusinessException(SeckillCodeMsg.OPT_SECKILL_ERROR);
        }

        //判断商品是否在活动时间内
        SeckillProductVo seckillProductVo = seckillProductService.find(time, seckillId);

        /*boolean legalTime = DateUtil.isLegalTime(seckillProductVo.getStartDate(), time);
        if(!legalTime){
            throw new BusinessException(SeckillCodeMsg.OPT_SECKILL_ERROR);
        }*/

        //判断库存是否足够
        if(seckillProductVo.getStockCount() <= 0){
            throw new BusinessException(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }
        //判断是否重复下单
        String token = request.getHeader("token");
        UserInfo userInfo = UserUtil.getUser(redisTemplate, token);
        Boolean isExist = redisTemplate.opsForSet().isMember(SeckillRedisKey.SECKILL_ORDER_SET.getRealKey(time + ""), userInfo.getPhone() + ":" + seckillId);
        if(isExist){
            throw new BusinessException(SeckillCodeMsg.REPEAT_SECKILL);
        }
        //利用redis控制进入到service的人数
        Long count = redisTemplate.opsForHash().increment(SeckillRedisKey.SECKILL_STOCK_COUNT_HASH.getRealKey(time + ""), seckillId + "", -1);
        if(count < 0){
            //存入true，表明已经没有库存了
            local_flag.put(seckillId,true);
            throw new BusinessException(SeckillCodeMsg.SECKILL_STOCK_OVER);
        }

        //执行秒杀业务逻辑，需要返回一个订单编号，前端需要通过订单编号查询订单详情
        //String orderNum = orderInfoService.doSeckill(time,seckillId,userInfo.getPhone());
        //把数据封装成消息发送到mq，前端需要去跟websocket建立连接，而不是直接跳转到订单详情页面
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setSeckillId(seckillId);
        orderMessage.setTime(time);
        orderMessage.setToken(token);
        orderMessage.setUserPhone(userInfo.getPhone());
        rocketMQTemplate.sendOneWay(MQConstant.ORDER_PEDDING_TOPIC,orderMessage);

        return Result.success("秒杀抢购中，请稍等...");
    }


}
